home *** CD-ROM | disk | FTP | other *** search
- /*
- * -- thread.c.1
- * Tests the thread-specific data API.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include "utils.h"
-
- #define ITERATIONS ((int)1000000)
- #define NUM_THREADS ((int)1)
- #define MAX_NAME_SIZE ((size_t) 24)
-
- static void
- destroy_data( void *data );
-
- typedef struct FULL_NAME
- {
- char first[MAX_NAME_SIZE];
- char last[MAX_NAME_SIZE];
- } full_name_t;
-
- static pthread_t *th;
- static pthread_attr_t attr_h;
- static pthread_key_t name_key, address_key;
- static char *address = "40 Elm St.";
-
- void
- thread_proc( full_name_t *thread_name )
- {
- long sum = 0;
- int st, i;
- full_name_t *name = NULL;
- char *addr;
-
- for(i = 0; i < ITERATIONS; i++ )
- sum += 1;
-
- /*
- * -- Set the name and address of the thread.
- */
- st = pthread_setspecific( name_key, thread_name );
- CHECK(st, "pthread_setspecific()");
- st = pthread_setspecific( address_key, address );
- CHECK(st, "pthread_setspecific()");
-
- for(i = 0; i < ITERATIONS * 2; i++ )
- sum += 1;
-
- st = pthread_getspecific( name_key, (void **) &name );
- CHECK(st, "pthread_getspecific()");
- st = pthread_getspecific( address_key, (void **) &addr );
- CHECK(st, "pthread_getspecific()");
-
- for(i = 0; i < ITERATIONS; i++ )
- sum += 1;
-
- printf_r("%s %s\n", name->first, name->last );
- printf_r("%s\n", addr );
-
- pthread_exit( (void *) SUCCESS );
- }
-
- static pthread_once_t key_once = PTHREAD_ONCE_INIT;
-
- static void
- init_key( void )
- {
- int st;
-
- st = pthread_key_create( &name_key, destroy_data );
- CHECK(st, "pthread_key_create()");
-
- st = pthread_key_create( &address_key, NULL );
- CHECK(st, "pthread_key_create()");
- }
-
- int
- main( int argc, char *argv[] )
- {
- int i, st, exit_val = 0, thread_count = NUM_THREADS;
- full_name_t *full_name;
-
- if( argc == 2 )
- thread_count = atoi( argv[1] );
-
- st = pthread_once( &key_once, init_key );
- CHECK(st, "pthread_once()");
-
- /*
- * -- Since threads are created, by default, as detached, then
- * we must create them with an attributes object initialized
- * with the PTHREAD_CREATE_JOINABLE attribute.
- */
- st = pthread_attr_init( &attr_h );
- CHECK(st, "pthread_attr_init()");
- st = pthread_attr_setdetachstate( &attr_h, PTHREAD_CREATE_JOINABLE );
- CHECK(st, "pthread_attr_setdetachstate()");
-
- /*
- * -- Create and join a bunch of threads.
- */
- th = malloc_r( thread_count * sizeof( pthread_t ));
- for(i = 0; i < thread_count; i++ )
- {
- full_name = malloc_r( sizeof( full_name_t ));
- pthread_lock_global_np();
- sprintf( full_name->first, "%s_%d", "bob", i );
- sprintf( full_name->last, "%s_%d", "smith", i );
- pthread_unlock_global_np();
-
- st = pthread_create( &th[i],
- &attr_h,
- (thread_proc_t) thread_proc,
- (void *) full_name );
-
- CHECK(st, "pthread_create()");
- }
-
- /*
- * -- Join with each one. The pthread_join() function automatically
- * detaches the thread once the join is complete. This means that
- * a thread may be joined only once.
- */
- for(i = 0; i < thread_count; i++ )
- {
- st = pthread_join( th[i], (void **) &exit_val );
- CHECK(st, "pthread_join()");
-
- if( exit_val != SUCCESS )
- fprintf_r( stderr, "Failed to join with th[%d]!\n", i);
- }
-
- st = pthread_attr_destroy( &attr_h );
- CHECK(st, "pthread_attr_destry()");
-
- free_r( th );
-
- for(i = 0; i < ITERATIONS; i++ )
- ;
-
- print_system_counters();
- return( EXIT_SUCCESS );
- }
-
- static void
- destroy_data( void *data )
- {
- free_r( data );
- }
-